const PENDING = 'pending'
const FUILFILLED = 'fuilfilled'
const REJECTED = 'rejected'


class MyPromise {
  constructor(executor) {
    try {
      executor(this.resolve, this.reject)
    } catch (error) {
      this.reason(error)
    }
  }

  status = PENDING

  value = undefined
  reason = undefined

  successCallBack = []
  failCallBack = []

  resolve = value => {
    if (this.status !== PENDING) return
    this.status = FUILFILLED
    this.value = value
    this.successCallBack.map(cb => cb(this.value))
  }

  reject = reason => {
    if (this.status !== PENDING) return
    this.status = REJECTED
    this.reason = reason
    this.failCallBack.map(cb => cb(this.reason))
  }

  then (successCallBack, failCallBack) {
    // 如果没传回调，给一个默认值 v=>v
    successCallBack = typeof successCallBack === 'function' ? successCallBack : v => v
    // 失败的回调默认值 
    failCallBack = typeof failCallBack === 'function' ? failCallBack : r => { throw r }
    // 为了实现then 的链式调用，需要返回一个promise
    const promise2 = new MyPromise((resolve, reject) => {
      setTimeout(() => { // 需要获取到promise2，但是代码执行的实话，还拿不到promise2
        // 如果状态是成功，执行successCallBack
        if (this.status === FUILFILLED) {
          // x 可能返回的是promise 对象，需要进行处理
          try {
            const x = successCallBack(this.value)
            resolvePromise(promise2, x, resolve, reject)
          } catch (error) {
            reject(error)
          }

        } else if (this.status === REJECTED) {
          // 如果状态失败，执行failCallBack
          // x 可能返回的是promise 对象，需要进行处理
          try {
            const x = failCallBack(this.reason)
            resolvePromise(promise2, x, resolve, reject)
          } catch (error) {
            reject(error)
          }
        } else {
          // 如果状态是等待，需要将回调缓存，状态改变的时候才调用
          this.successCallBack.push(() => {
            // 当promise 的状态的为pending 的时候，需要特别缓存，绑定this指向
            try {
              const x = successCallBack(this.value)
              resolvePromise(promise2, x, resolve, reject)
            } catch (error) {
              reject(error)
            }

          })
          this.failCallBack.push(() => {
            try {
              const x = failCallBack(this.value)
              resolvePromise(promise2, x, resolve, reject)
            } catch (error) {
              reject(error)
            }
           
          })
        }
      })

    })

    return promise2
  }


}
function resolvePromise (promise, x, resolve, reject) {
  if (promise === x) {
    throw '不能返回当前promise，会发生循环调用'
  }
  if (x instanceof MyPromise) {
    x.then(resolve, reject)
  } else {
    resolve(x)
  }
}
module.exports = MyPromise
